﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfellerpp
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System.Linq;
using System.Linq.Expressions;
using InterLinq.Client;
using InterLinq.Expressions;
using Sebarf.Core.Interfaces;
using Sebastof.Core.Services.Interfaces;

#endregion

namespace InterLinq.Sebarf {
	/// <summary>
	/// Client implementation of the <see cref="InterLinqQueryProvider"/>.
	/// </summary>
	/// <seealso cref="InterLinqQueryProvider"/>
	/// <seealso cref="IQueryProvider"/>
	public class SebarfBasedLinqQueryGateway : LinqQueryGateway {
		#region Property Handler

		/// <summary>
		/// Gets the <see cref="IQueryRemoteHandler"/>;
		/// </summary>
		public IRequestHandlerEngine Handler { get; private set; }

		public IServiceLocatorService ServiceLocatorService { get; private set; }

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes this class.
		/// </summary>
		/// <param name="queryRemoteHandler"><see cref="IQueryRemoteHandler"/> to communicate with the server.</param>
		/// <param name="context">metadata</param>
		public SebarfBasedLinqQueryGateway(IServiceLocatorService locator, IRequestHandlerEngine handler) {
			Handler = handler;
			ServiceLocatorService = locator;
		}

		#endregion

		#region Methods

		/// <summary>
		/// Executes the query and returns the requested data.
		/// </summary>
		/// <typeparam name="TResult">Type of the return value.</typeparam>
		/// <param name="expression"><see cref="Expression"/> tree to execute.</param>
		/// <returns>Returns the requested data of Type 'TResult'.</returns>
		/// <seealso cref="InterLinqQueryProvider.Execute"/>
		public TResult Execute<TResult>(Expression expression) {
			object rest = Execute(expression);

			// deserialize

			if (rest == null) {
				return default(TResult);
			}
			//ServiceLocatorService.GetRegisteredService<IDeserializationSetTargetTypeService>().SetTargetType(typeof(TResult));
			return
				(TResult)
				ServiceLocatorService.GetRegisteredService<IObjectTransmissionService>().PrepareTransmittedObjectForUsing(
					typeof(TResult), rest);

			//return (TResult)TypeConverter.ConvertFromSerializable(locator, typeof(TResult), Execute(expression));
		}

		/// <summary>
		/// Executes the query and returns the requested data.
		/// </summary>
		/// <param name="expression"><see cref="Expression"/> tree to execute.</param>
		/// <returns>Returns the requested data of Type <see langword="object"/>.</returns>
		/// <seealso cref="InterLinqQueryProvider.Execute"/>
		public object Execute(Expression expression) {
			SerializableExpression serExp = expression.MakeSerializable();
			object receivedObject = Handler.Process(new ExecuteLinqQueryRequest(serExp));
			return receivedObject;
		}

		#endregion
	}
}